﻿using Core.Framework.Redis.Queue_Helper;
using Core.Framework.Util;
using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using System.Xml;

namespace Core.Middleware.XMLDiscription
{
    public class XMLDiscriptionMidWare
    {
        private readonly RequestDelegate requestDelegate;

        public XMLDiscriptionMidWare(RequestDelegate requestDelegate)
        {
            this.requestDelegate = requestDelegate;
        }

        public async Task Invoke(HttpContext context)
        {
            if (context.Request.Path == "/v1/.getType")
            {
                context.Response.ContentType = "application/json";

                // 用户身份验证
                if (this.UserAuthorize(context.Request.Headers))
                {
                    await context.Response.WriteAsync(new
                    {
                        code = 60003,
                        info = "接口禁止访问"
                    }.TryToJson());
                }
                else
                {
                    await context
                        .Response
                        .WriteAsync(
                            this.GetControllerDesc(context.Request.QueryString.ToString().TrimStart('?')).TryToJson());
                }

            }
            else {
                await requestDelegate(context);
            }
        }

        /// <summary>
        /// 用户身份验证
        /// </summary>
        /// <param name="header"></param>
        /// <returns></returns>
        private bool UserAuthorize(IHeaderDictionary header)
        {

            var token = header["itool-token"].ToString();

            if (!string.IsNullOrWhiteSpace(token))
            {
                var result
                    = RedisQueueHelper.HashGet(RedisQueueHelperParameter.ApiClientByToken, token);

                return !string.IsNullOrWhiteSpace(result);

            }

            return false;
        }



        private ConcurrentDictionary<string, TypeInfo> GetControllerDesc(string typeName)
        {

            ConcurrentDictionary<string, TypeInfo> controllerDescDict = new ConcurrentDictionary<string, TypeInfo>();


            List<string> XmlFiles = this.GetXMLFiles();

            string tttt = string.Empty;

            if (typeName.ToUpper().StartsWith("F:"))
                tttt = "F:";

            else if (typeName.ToUpper().StartsWith("T:"))
                tttt = "T:";

            else if (typeName.ToUpper().StartsWith("M:"))
                tttt = "M:";

            else if (typeName.ToUpper().StartsWith("P:"))
                tttt = "P:";

            if (!string.IsNullOrWhiteSpace(tttt))
            {
                typeName = typeName.Split(':')[1];
            }
            


            foreach (var item in XmlFiles)
            {
                var xmlpath = Path.Combine(item);

                if (File.Exists(xmlpath))
                {
                    XmlDocument xmldoc = new XmlDocument();
                    xmldoc.Load(xmlpath);

                    foreach (XmlNode node in xmldoc.SelectNodes("//member"))
                    {
                        string type = node.Attributes["name"].Value;
                        if (type.ToLower().IndexOf(typeName.ToLower()) > -1)
                        {

                            if (!string.IsNullOrWhiteSpace(tttt))
                            {
                                if (!type.ToUpper().StartsWith(tttt))
                                    continue;
                            }


                            string tag = string.Empty;

                            if (type.StartsWith("F:"))
                                tag = "枚举";

                            else if (type.StartsWith("T:"))
                                tag = "类型";

                            else if (type.StartsWith("M:"))
                                tag = "方法";

                            else if (type.StartsWith("P:"))
                                tag = "属性";

                            


                            //获取控制器注释
                            XmlNode summaryNode = node.SelectSingleNode("summary");

                            if (summaryNode != null && !string.IsNullOrEmpty(summaryNode.InnerText))
                            {
                                controllerDescDict.TryAdd($"{type}",new TypeInfo {
                                    Discription = summaryNode.InnerText.Trim(),
                                    Tag = tag,
                                    Parameters = node.SelectSingleNode("param")
                                });
                            }

                        }
                    }
                }
            }

            

            return controllerDescDict;
        }


        private List<string> GetXMLFiles()
        {
            string s = null;
            DirectoryInfo d = new DirectoryInfo(AppContext.BaseDirectory);
            FileInfo[] Files = d.GetFiles("*.xml");
            List<string> lstr = new List<string>();

            foreach (FileInfo file in Files)
            {
                s = file.FullName;
                lstr.Add(s);
            }

            return lstr;
        }

        class TypeInfo
        {
            public string Tag { get; set; }

            public string Discription { get; set; }

            public object Parameters { get; set; }
        }


    }
}
